//
//  AccountService.m
//  YuanXinKit
//
//  Created by 晏德智 on 2016/11/23.
//  Copyright © 2016年 晏德智. All rights reserved.
//

#import "AccountManager.h"
#import "UserService.h"
#import "YuanXinKeyChainManager.h"
#import "AppStateSyncService.h"
#import "NetworkingManager.h"

#define yxLoginSuccess @"loginSuccess"
#define yxRefreshToken @"refreshToken"
#define yxLoginOut @"loginOut"
// yuanxintrack 组件中定义了这个 key，这里复用下
#define kLogCurrentUserIDKey @"YuanXinLogCurrentUserIDKey"
#define kPushTokenStorageKey @"yuanxinpushToken"

@interface AccountManager () <OAuthInfoObserver>

@end

@implementation AccountManager

RCT_EXPORT_MODULE();

- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

//https://github.com/facebook/react-native/issues/15421
//RCTEventEmitter bridge is not set #15421
//You shouldn't init RCTCameraEvent yourself. It will be initialized by react native. You must try to communicate with that instance in some way. For example your AppDelegate may send a notification which RCTCameraEvent subscribes to on init. You may then forward that information to js using the [self sendEventWithName:@"CustomEvent" body:@{@"name": @"111"}];
- (instancetype)init
{
    self = [super init];
    if (self) {
        [[NetworkingManager shareInstance] addOAuthInfoObserver:self];
    }
    return self;
}

/**
 */
RCT_EXPORT_METHOD(UserLogin:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)recject){
    
    NSString *userName = [options objectForKey:@"username"];
    if(userName && userName.length >0)
    {
        __block RCTPromiseResolveBlock  successBlock = nil;
        if(resolve){
            successBlock =[resolve copy];
        }
        __block RCTPromiseRejectBlock  errorBlock = nil;
        if(recject){
            errorBlock=  [recject copy];
        }
        
        NSMutableDictionary *mParams = [options mutableCopy];
        
        [UserService loginParams:mParams
                       success:^(NSDictionary *data){
                           __block NSMutableDictionary *blockData = [data mutableCopy];
                           if (blockData[@"open_id"]) {
                               // 存储本地当前登录人
                               [[NSUserDefaults standardUserDefaults] setObject:blockData[@"open_id"] forKey:kLogCurrentUserIDKey];
                           }
                           
                           //把常用的数据存储本地。
                           //IM 登录  回调成功，登录到IM
                           //[UserService shareInstance] IMlogin:
                           //存储本地，开始IM 通道，后台线程获取离线消息(IM)
                           [UserService IMLogin:^(NSDictionary *imData){
                               NSString *assetToken = [imData objectForKey:@"imConnectionId"];
                               NSNumber *userNumber = [imData objectForKey:@"userId"];
                               [[NSUserDefaults standardUserDefaults] setObject:assetToken forKey:@"imConnectionId"];
                               [[NSUserDefaults standardUserDefaults] setObject:userNumber forKey:@"imUserID"];
                               NSMutableDictionary *resultData = [NSMutableDictionary dictionaryWithDictionary:blockData];
                               [resultData addEntriesFromDictionary:imData];
                               RCTExecuteOnMainQueue(^{
                                   [[NSNotificationCenter defaultCenter] postNotificationName:yxLoginSuccess object:resultData userInfo:nil];
                               });
                               if(successBlock){
                                   successBlock(resultData);
                               }
                           } failure:^(NSError *error){
                               NSLog(@"IMLogin %@",error);
                               NSMutableDictionary *resultData = [NSMutableDictionary dictionaryWithDictionary:blockData];
                               RCTExecuteOnMainQueue(^{
                                   [[NSNotificationCenter defaultCenter] postNotificationName:yxLoginSuccess object:resultData userInfo:nil];
                               });
                               if(successBlock){
                                   successBlock(resultData);
                               }
                           }];
                       } failure:^(NSError *error){
                           NSDictionary *errResponse = error.userInfo ? [NSJSONSerialization JSONObjectWithData:error.userInfo[@"com.alamofire.serialization.response.error.data"] options:NSJSONReadingMutableLeaves error:nil] : nil;
                           if(recject){
                               NSString *errorCode = @(error.code).stringValue;
                               NSString *errorMessage = error.localizedDescription;
                               if (errResponse && errResponse[@"ErrorCode"]) {
                                   errorCode = [errResponse[@"ErrorCode"] stringValue];
                                   errorMessage = errResponse[@"ErrorMsg"];
                               }
                               recject(errorCode, errorMessage, error);
                           }
                       }];
        
        
    }else
    {
        NSDictionary *userInfo = @{ NSLocalizedDescriptionKey:@"用户名或密码不能为空" };
        NSError *errorInfo = [NSError errorWithDomain:@"validationerror"
                                                 code:@(-1).integerValue
                                             userInfo:userInfo];
        recject(@(-1).stringValue, @"validationerror", errorInfo);
    }
    
}

RCT_EXPORT_METHOD(RefreshToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)recject){
    __block RCTPromiseResolveBlock  successBlock = nil;
    if(resolve){
        successBlock =[resolve copy];
    }
    __block RCTPromiseRejectBlock errorBlock = nil;
    if(recject){
        errorBlock=  [recject copy];
    }
    
    [UserService refreshToken:^(NSDictionary *data) {
        //把常用的数据存储本地。
        //IM 登录  回调成功，登录到IM
        //__block NSMutableDictionary *blockData = [data mutableCopy];
        NSString *assetToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"imConnectionId"];
        NSNumber *userNumber = [[NSUserDefaults standardUserDefaults] objectForKey:@"imUserID"];
        if(assetToken && userNumber){
            NSMutableDictionary *resultData = [NSMutableDictionary dictionaryWithDictionary:data];
            [resultData setObject:assetToken forKey:@"imConnectionId"];
            [resultData setObject:userNumber forKey:@"userId"];
            RCTExecuteOnMainQueue(^{
                [[NSNotificationCenter defaultCenter] postNotificationName:yxRefreshToken object:resultData userInfo:nil];
            });
            if(successBlock){
                successBlock(resultData);
            }
        }else {
            __block NSMutableDictionary *blockData = [data mutableCopy];
            [UserService IMLogin:^(NSDictionary *imData){
                NSString *assetToken = [imData objectForKey:@"imConnectionId"];
                NSNumber *userNumber = [imData objectForKey:@"imUserID"];
                [[NSUserDefaults standardUserDefaults] setObject:assetToken forKey:@"imConnectionId"];
                [[NSUserDefaults standardUserDefaults] setObject:userNumber forKey:@"imUserID"];
                NSMutableDictionary *resultData = [NSMutableDictionary dictionaryWithDictionary:blockData];
                [resultData addEntriesFromDictionary:imData];
                RCTExecuteOnMainQueue(^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:yxRefreshToken object:resultData userInfo:nil];
                });
                if(successBlock){
                    successBlock(resultData);
                }
            } failure:^(NSError *error){
                NSLog(@"IMLogin %@",error);
                NSMutableDictionary *resultData = [NSMutableDictionary dictionaryWithDictionary:blockData];
                RCTExecuteOnMainQueue(^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:yxRefreshToken object:resultData userInfo:nil];
                });
                if(successBlock){
                    successBlock(resultData);
                }
            }];
        }
    } failure:^(NSError *error) {
        if(errorBlock){
            errorBlock(@(error.code).stringValue, error.localizedDescription, error);
        }
    }];
}

RCT_EXPORT_METHOD(loginOut:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)recject){
    
    __block RCTPromiseResolveBlock  successBlock = nil;
    if(resolve){
        successBlock =[resolve copy];
    }
    __block RCTPromiseRejectBlock  errorBlock = nil;
    if(recject){
        errorBlock=  [recject copy];
    }
    
    [UserService loginOut:^(id success) {
        //本地存的 pushToken
        NSString *pushToken = [[NSUserDefaults standardUserDefaults] stringForKey:kPushTokenStorageKey];
        //调用解绑 pushToken 接口
        if (pushToken) {
            [AppStateSyncService unbindingDeviceTokenToServer:pushToken];
        }
        RCTExecuteOnMainQueue(^{
            [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"imConnectionId"];
            [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"imUserID"];
            [[NSUserDefaults standardUserDefaults] removeObjectForKey:kLogCurrentUserIDKey];
            // 发“登出”通知，IM 那里接收到该通知会断开 socket 连接
            [[NSNotificationCenter defaultCenter] postNotificationName:yxLoginOut object:nil];
        });
        if(successBlock){
            successBlock(success);
        }
        
    } failure:^(NSError *error) {
        if(errorBlock){
            errorBlock(@(error.code).stringValue, error.description, error);
        }
    }];
}


#if __has_include(<React/RCTEventEmitter.h>)
- (void)startObserving
{
    [[NetworkingManager shareInstance] addOAuthInfoObserver:self];
}

- (void)stopObserving
{
    [[NetworkingManager shareInstance] removeOAuthInfoObserver:self];
}

- (NSArray<NSString *> *)supportedEvents{
    return @[@"refreshToken",@"loginOut"];
}
#endif

- (void)postMessgeNotif:(NSDictionary *)data messageType:(NSString *)type{
    
#if __has_include(<React/RCTEventEmitter.h>)
    if (self.bridge) { //RCTEventEmitter bridge is not set #15421
        [self sendEventWithName:type body:data];
    }
#else
    if (self.bridge) {
        [self.bridge.eventDispatcher sendDeviceEventWithName:type
                                                        body:data];
    }
#endif
    
}


#pragma mark -- OAuthInfoObserver

- (void)onUnauthorized {
    __weak typeof (self) weakSelf = self;
    
    [UserService refreshToken:^(NSDictionary *data) {
        //把常用的数据存储本地。
        //IM 登录  回调成功，登录到IM
        NSMutableDictionary *rdata =  [data mutableCopy];
        [weakSelf postMessgeNotif:rdata messageType:@"refreshToken"];
        RCTExecuteOnMainQueue(^{
            [[NSNotificationCenter defaultCenter] postNotificationName:yxRefreshToken object:rdata userInfo:nil];
        });
        
    } failure:^(NSError *error) {
        //TODO:todo->gjs:这里一般是接口报401然后刷新token也失败了的情况会进(可以视为“下线了”)，是否需要删除本地存储的当前登录人
        //TODO:todo->gjs:这里是否要调用解绑 pushToken 接口?
        //本地存的 pushToken
        NSString *pushToken = [[NSUserDefaults standardUserDefaults] stringForKey:kPushTokenStorageKey];
        //调用解绑 pushToken 接口
        if (pushToken) {
            [AppStateSyncService unbindingDeviceTokenToServer:pushToken];
        }
        [weakSelf postMessgeNotif:error.userInfo messageType:@"loginOut"];
        RCTExecuteOnMainQueue(^{
            [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"imConnectionId"];
            [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"imUserID"];
            [[NSUserDefaults standardUserDefaults] removeObjectForKey:kLogCurrentUserIDKey];
            // 发“登出”通知，IM 那里接收到该通知会断开 socket 连接
            [[NSNotificationCenter defaultCenter] postNotificationName:yxLoginOut object:nil];
        });
    }];
    
}

@end
